<?php
/**
 * 验证码类
 * 
 * @version $Id: Captcha.php 174 2011-05-18 02:38:13Z linsir123 $
 */
class comCaptcha
{
	///
	public $im;
	public $code;
	public $expired;
	public $options = array('bordercolor'=>null);
	public $width;
	public $height;
	
	/**
     * 构造函数
     */
	public function __construct($width = 70, $height = 21, $options = array())
	{
		@session_start();
		$this->code = isset($_SESSION['CaptchaCode']) ? $_SESSION['CaptchaCode'] : '';
		$this->expired = isset($_SESSION['CaptchaExpired']) ? $_SESSION['CaptchaExpired'] : 0;
		$this->options = array_merge($this->options, $options);
		$this->width = $width;
		$this->height = $height;
	}
	
	/**
	 * 生成背景
	 */
	private function _background()
	{
		$this->im = imagecreate($this->width, $this->height);
		
		///
		for($i = 0; $i < 3; $i++) {
			$start[$i] = mt_rand(200, 255);
			$end[$i] = mt_rand(100, 150);
			$step[$i] = ($end[$i] - $start[$i]) / $this->width;
			$c[$i] = $start[$i];
		}
		for($i = 0; $i < $this->width; $i++) {
			$color = imagecolorallocate($this->im, $c[0], $c[1], $c[2]);
			imageline($this->im, $i, 0, $i, $this->height, $color);
			$c[0] += $step[0];$c[1] += $step[1];$c[2] += $step[2];
		}
		
		///
		$linenums = $this->height / 10;
		for($i=0; $i <= $linenums; $i++) {
			$color = imagecolorallocate($this->im, mt_rand(0, 255), mt_rand(0, 255), mt_rand(0, 255));
			$x = mt_rand(0, $this->width);
			$y = mt_rand(0, $this->height);
			if (mt_rand(0, 1))
				imagearc($this->im, $x, $y, mt_rand(0, $this->width), mt_rand(0, $this->height), mt_rand(0, 360), mt_rand(0, 360), $color);
			else
				imageline($this->im, $x, $y, $linex + mt_rand(0, $linemaxlong), $liney + mt_rand(0, mt_rand($this->height, $this->width)), $color);
		}
		
		///
		if ($this->options['bordercolor']) {
			list($r, $g, $b) = lpString::hex2rgb($this->options['bordercolor']);
			$color = imagecolorallocate($this->im, $r, $g, $b);
			imagerectangle($this->im, 0, 0, $this->width - 1, $this->height - 1, $color);
		}
	}
	
	/**
	 * 生成字体
	 */
	private function _ttfont()
	{
		$widthtotal = 0;
		$seccode = $this->code;
		$seccodelength = strlen($seccode);
		for ($i = 0; $i < $seccodelength; $i++) {
			$font[$i]['font'] = dirname(__FILE__).DS.'fonts/verdanab.ttf';
			$font[$i]['size'] = 12;
			$box = imagettfbbox($font[$i]['size'], 0, $font[$i]['font'], $seccode[$i]);
			$font[$i]['height'] = max($box[1], $box[3]) - min($box[5], $box[7]);
			$font[$i]['width'] = (max($box[2], $box[4]) - min($box[0], $box[6])) + mt_rand(0, $this->width / 8);
			$font[$i]['width'] = $font[$i]['width'] > $this->width / $seccodelength ? $this->width / $seccodelength : $font[$i]['width'];
			$widthtotal += $font[$i]['width'];
		}
		
		///
		$x = mt_rand(1, $this->width - $widthtotal);
		for ($i = 0; $i < $seccodelength; $i++) {
			$fontcolor = array(mt_rand(0, 255), mt_rand(0, 255), mt_rand(0, 255));
			$text_shadowcolor = imagecolorallocate($this->im, 255 - $fontcolor[0], 255 - $fontcolor[1], 255 - $fontcolor[2]);
			$text_color = imagecolorallocate($this->im, $fontcolor[0], $fontcolor[1], $fontcolor[2]);
			$y = mt_rand($font[$i]['height'] + 2, $this->height - 5);
			imagettftext($this->im, $font[$i]['size'], 0, $x + 1, $y + 1, $text_shadowcolor, $font[$i]['font'], $seccode[$i]);
			imagettftext($this->im, $font[$i]['size'], 0, $x, $y, $text_color, $font[$i]['font'], $seccode[$i]);
			$x += $font[$i]['width'];
		}
	}
	
	/**
     * 生成图像
     */
	public function display($type = 0)
	{
		switch ($type) {
			case 1:
				$seed = '0123456789';
				break;
			case 2:
				$seed = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
				break;
			default:
				$seed = '012346789ABCDEFGHJKLMNPQRTUVWXYZabcdefghijklmnopqrstuvwxyz';
				break;
		}
		
		///
		$this->code = '';
		list($usec, $sec) = explode(' ', microtime());
		srand($sec + $usec * 100000);
		for ($i = 0; $i < 4; $i++) 
			$this->code .= substr($seed, rand(0, strlen($seed) - 1), 1);
		
		$_SESSION['CaptchaCode'] = $this->code;
		$_SESSION['CaptchaExpired'] = $this->expired = time() + 900;
		
		///
		$this->_background();
		$this->_ttfont();
		header('Content-type:image/png');
		imagepng($this->im);
		imagedestroy($this->im);
	}
    
	/**
     * 检验验证码是否输入正确
     */
	public function check($code)
	{
		return (time() < $this->expired && strtoupper($code) == strtoupper($this->code));
	}
}
